home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / adikit.arc / DSHERCA.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-12-01  |  14.1 KB  |  595 lines

  1.     title    DSHERC.ASM
  2.     name    DSHERC
  3. include    DOS.MAC
  4. ;
  5. ;    Assembler routines for the Hercules display driver.  Mostly
  6. ;    Graphics-mode, but a little text-mode stuff.  In graphics mode,
  7. ;       we deal strictly in "natural" screen coordinates, i.e., with
  8. ;    the origin at the upper    left corner.
  9.  
  10. ;    Addition of an optional    status line at the top of the screen is
  11. ;    handled    rather uncleanly by just knowing that certain fields start
  12. ;       14 pixels lower than otherwise.  To this routine, the "graphics
  13. ;       area" is the rectangle swept by the crosshairs and cleared by
  14. ;    dsclr; it is  graphx  by  graphy  pixels.
  15.  
  16. ;    Note that the byte-oriented references in adsmark, adsclr, adschar,
  17. ;    and hcscroll is    done purposely to accomodate an    unfortunate design
  18. ;    choice in the way the Eagle Computer addresses video ram.
  19.  
  20. ;    Modified 2/10/84:  byte-oriented code for Eagle    and saving and 
  21. ;    restoring es.
  22.  
  23. ;    Final 1.50 update 6/20/84      
  24.  
  25. ;;;;;;;    public    finddot
  26.     public    adsvec,adsxvec,adsmark,adsclr,adswipe
  27.     public    adsdot
  28.     public    adschar,dsrvid
  29.     public    hcscroll
  30.  
  31.  
  32. graphseg equ    0B800h        ;Graphics buffer (page 1)
  33. textseg    equ    0B000h        ;Text buffer (page 0)
  34. XSIZE    equ    720        ;Nr of vertical    columns.
  35. YSIZE    equ    348        ;Nr of horizontal lines.
  36. below_cline equ    270+4000h    ;First pixel below status line.
  37.  
  38.  
  39.     dseg    dsherca        ;Display driver    data
  40.  
  41.     extrn    color:word    ;Color to draw anything.
  42.     extrn    hilight:word    ;Highlight selected entities flag
  43.     extrn    graphx:word    ;Graphics area width
  44.     extrn    graphy:word    ;  and height.
  45.     extrn    cline:word    ;Status    line flag.
  46.  
  47.  
  48. ninety    dw    90        ;Number    of bytes per row.
  49. hibits    db    00000000b    ;Bits 14 & 13 of vram address.
  50.     db    00100000b
  51.     db    01000000b
  52.     db    01100000b
  53. xmask    db    0        ;Clear-pixel mask for dsvec.
  54.  
  55. chartab    equ    this byte    ;Font definition table (see adschar)
  56.     include    hcfont.ai    ;In a separate module.
  57.  
  58.  
  59.     endds    dsherca
  60. ;
  61. ;
  62.     pseg    dsherca_
  63.  
  64.  
  65. ;    Internal routine to convert screen coordinates to graphics buffer
  66. ;    address.  Takes    x-coordinate at    ARGS, y-coordinate at ARGS+2,
  67. ;    returns    byte address in    bx, bit    number in cl (0=left).
  68.  
  69. ;    Incidentally returns byte address of dot at (0,y) in ax.
  70.  
  71. ;    Clobbers dx.
  72.  
  73. hcdot    proc    near
  74.     mov    ax,args+2    ;Row number.
  75.     mov    bx,ax        ;a copy.
  76.     shr    ax,1        ;Divide    by
  77.     shr    ax,1        ;   4 and multiply
  78.     mul    ninety        ;   by 90.
  79.     and    bx,11b        ;Low 2 bits of row number.
  80.     or    ah,hibits[bx]    ;Move to bits 14 and 13.
  81.     mov    bx,args        ;column    number.
  82.     mov    cl,bl        ;Copy it.
  83.     shr    bx,1        ;Divide    by 8.
  84.     shr    bx,1
  85.     shr    bx,1
  86.     and    cl,111b        ;Bit number.
  87.     add    bx,ax        ;Byte address.
  88.     ret
  89. hcdot    endp
  90.  
  91. ;    Return dot location to a c program.
  92.  
  93. ;    finddot(x, y, &byte, &dot)
  94.  
  95.         ifdef   NEEDED          ;So far, it isn't.
  96. finddot    proc    far
  97.     push    bp
  98.     mov    bp,sp
  99.     call    hcdot        ;Do the    computation.
  100.     xor    ch,ch        ;Zero-extend cl.
  101.     mov    si,args+4    ;Store
  102.     mov    [si],bx        ;   byte number,
  103.     mov    si,args+6    ;   dot    number.
  104.     mov    [si],cx
  105.     pop    bp
  106.     ret
  107. finddot    endp
  108.     endif
  109.  
  110.  
  111.  
  112. ;    Complement the dot at screen coordinates (x,y)
  113. ;
  114. ;    adsdot(x,y)
  115. ;
  116. adsdot    proc    far
  117.     push    bp        ;Get a stack frame.
  118.     mov    bp,sp
  119.     push    es        ; always save seg regs
  120.     call    hcdot        ;Locate    the dot    in vram.
  121.     mov    ax,graphseg    ;Base
  122.     mov    es,ax        ;   graphics RAM segment.
  123.     mov    al,10000000b    ;xor mask.
  124.     ror    al,cl        ;Position it over pixel.
  125.     xor    es:[bx],al    ;Flip the pixel.
  126.     pop    es        ; restore ES
  127.     pop    bp        ;And stack frame.
  128.     ret
  129. adsdot    endp
  130. ;
  131. ;
  132. ;    call adsvec(x1,    y1, x2,    y2)
  133. ;
  134. ;        to draw a vector from (x1,y1) to (x2,y2) in    current    color.
  135. ;
  136. ;    call adsxvec(x1, y1, x2, y2)
  137. ;
  138. ;        to complement dots of vector from (x1,y1) to (x2,y2).
  139. ;
  140. rangex    equ    word ptr -2[bp]    ;abs(x2-x1)
  141. rangey    equ    word ptr -4[bp]    ;abs(y2-y1)
  142. yincalt    equ    word ptr -6[bp]    ;address addend    for y incrementation.
  143. patmask    equ    byte ptr -8[bp]    ;line font pattern mask
  144. tempsiz    equ    8
  145. ;
  146. adsvec    proc    far
  147.     mov    al,01111111b    ;Clear-pixel mask.
  148.     jmp    veccmn        ;Join adsxvec.
  149.  
  150. adsxvec    label    far
  151.         mov     al,11111111b    ;Don't clear pixel.
  152.  
  153. veccmn:
  154.     mov    xmask,al    ;Save mask (and    flag).
  155.     push    bp
  156.     mov    bp,sp        ;Make ourselves    a stack    frame.
  157.     sub    sp,tempsiz    ;Reserve local variables.
  158.     mov    si,args+6    ;y2
  159.     mov    cx,args+2    ;y1
  160.     sub    si,cx        ;y2-y1
  161.     mov    dx,args+4    ;x2
  162.     mov    bx,args        ;x1
  163.     sub    dx,bx        ;x2-x1
  164.     mov    rangex,dx
  165.     mov    rangey,si
  166.     mov    patmask,11111111b ;set solid line pattern
  167.  
  168. ;    To simplify the    incrementation of x in the drawing loop, we start
  169. ;    from the point with smaller x-coordinate.
  170.     push    bp        ;Save for temp stack frame change.
  171.     jge    noswap
  172.     neg    rangex
  173.     neg    rangey
  174.     add    bp,4        ;Starting point    is P2, not P1.
  175. noswap:
  176.     call    hcdot        ;Get starting address in bx and    cl.
  177.     pop    bp        ;Make sure stack frame is right.
  178.  
  179. ;    Moving up or down one row is accomplished by adding plus or minus
  180. ;    2000h to the current byte address, and when that overflows (every
  181. ;    4 lines), adding plus or minus (90-8000h).
  182.  
  183.     mov    si,2000H    ;Row-increment addend.
  184.     mov    di,90-8000H    ;Every-fourth-time correction.
  185.     test    byte ptr rangey+1,80h    ;If y difference is
  186.     jz    posy
  187.     neg    rangey        ;   negative, invert it,
  188.     neg    si        ;   invert the y addends
  189.     neg    di        ;   also.
  190. posy:    mov    yincalt,di    ;Save second y addend.
  191.  
  192. ;    al will    be used    to mask    the bit    for one    dot out    a byte,
  193. ;       then ah will be xor'ed with it.
  194.  
  195.     mov    al,xmask    ;the mask (and dsvec/dsxvec flag).
  196.     cmp    al,11111111b    ;If dsxvec,
  197.         je      xorit           ;   don't check color.
  198.     xor    ah,ah        ;Bit=1 unless color==0.
  199.     cmp    ah,byte    ptr color
  200.     je    dplus2
  201.  
  202.     cmp    ah,byte    ptr hilight ;Highlight vector ?
  203.     je    xorit        ; no.  skip pattern setup
  204.     mov    patmask,10101010b  ; set highlight pattern
  205.     push    ax
  206.     mov    ax,rangex
  207.     cmp    ax,rangey    ; Select pattern by movement direction
  208.     pop    ax
  209.     jl    xorit
  210.     mov    patmask,11001100b  ; set highlight pattern
  211.  
  212. xorit:
  213.     mov    ah,10000000B
  214. dplus2:
  215.     ror    ah,cl        ;Position to starting pixel.
  216.     ror    al,cl
  217.     ror    patmask,cl    ;Shift pattern mask to start pos
  218. ;
  219. ;
  220.     push    ds        ;Point ds to
  221.     mov    dx,graphseg    ;   video ram.
  222.     mov    ds,dx
  223.     xor    dx,dx        ;Zero relative-motion counter.
  224.     mov    cx,rangex    ;Loop on the coordinate
  225.     cmp    cx,rangey    ;   which has the
  226.     jl    loopony        ;   farthest to    move.
  227.  
  228. ;
  229. ;Loop is on x.
  230.     mov    di,cx        ;Value for comparison with relative-
  231.     shr    di,1        ;   motion counter to di.
  232.     inc    cx        ;One dot more than (x2-x1).
  233. xincloop:
  234.         and     [bx],al         ;Turn off dot's old color,
  235.     test    ah,patmask    ;Should    we set bit ?
  236.     jz    xincp        ;no.  skip it
  237.     xor    [bx],ah        ;   turn on with new.
  238.  
  239. ;    Advance    to next    dot to right.  We have wraparound if either
  240. ;       shift of ah generates a carry or shift of al doesn't.
  241.  
  242. xincp:    ror    ah,1
  243.     jnc    xnoinc1
  244.     ror    al,1
  245.     jmp    short xinc0
  246. xnoinc1:
  247.     ror    al,1
  248.     jc    xinc1        ;If it wrapped around,
  249. xinc0:
  250.     inc    bx        ;   advance to next byte.
  251. xinc1:
  252.     add    dx,rangey    ;If motion in x-direction is getting
  253.     cmp    dx,di        ;   ahead of motion in y-direction,
  254.     jle    xinc2
  255.     sub    dx,rangex    ;   correct relative-motion counter.
  256.     add    bx,si        ;Take a    step in    y-direction.
  257.     jns    xinc2        ;If overflow,
  258.     add    bx,yincalt    ;   correct ram    address.
  259. xinc2:    loop    xincloop
  260.     jmp    short vecret   ;Done.
  261. ;
  262. ;Loop on y.
  263. loopony:
  264.     mov    cx,rangey
  265.     mov    di,cx
  266.     shr    di,1
  267.     inc    cx
  268. yincloop:
  269.         and     [bx],al         ;Turn off dot's old color,
  270.     test    patmask,1    ;Should    we set bit ?
  271.     jz    yincp        ;no.  skip it
  272.     xor    [bx],ah        ;   turn on with new.
  273. yincp:    rol    patmask,1    ;Shift pattern mask one    position
  274.     add    bx,si        ;Take a    step in    y-direction.
  275.     jns    yinc1        ;If overflow,
  276.     add    bx,yincalt    ;   correct ram    address.
  277. yinc1:
  278.     add    dx,rangex    ;Update    relative-motion    counter.
  279.     cmp    dx,di
  280.     jle    yinc2
  281.     sub    dx,rangey
  282.     ror    ah,1        ;Increment x.
  283.     jnc    ynoinc1
  284.     ror    al,1
  285.     jmp    short yinc11
  286. ynoinc1:
  287.     ror    al,1
  288.     jc    yinc2        ;If it wrapped around,
  289. yinc11:
  290.     inc    bx        ;   advance to next byte.
  291. yinc2:    loop    yincloop
  292. ;
  293. vecret:
  294.     pop    ds
  295.     add    sp,tempsiz
  296.     pop    bp
  297.     ret
  298. adsvec endp
  299.  
  300. ;
  301. ;
  302. ;
  303. ;    call adsmark(x,y)
  304. ;
  305. ;    to reverse (draw or erase) the crosshairs centered at (x,y).
  306. ;
  307. adsmark    proc    far
  308. ;    Preliminaries:
  309.     push    bp
  310.     mov    bp,sp
  311.     push    es        ; always save seg regs
  312.     mov    ax,graphseg    ;Base graphics ram
  313.     mov    es,ax        ;   on es.
  314.  
  315.     call    hcdot        ;(x,y) dot in bit cl of    byte bx    (and set ax)
  316.     push    ax        ;Save (0,y) address.
  317.     sub    bx,ax        ;(x,0) address to bx,cl.
  318.     mov    dl,10000000B    ;Put a bit in
  319.     shr    dl,cl        ;   right column.
  320.  
  321.     mov    cx,graphy    ;Number    of rows.
  322.  
  323.         cmp     cline,0         ;If there's a
  324.     je    colloop        ;   status line,
  325.     add    bx,below_cline    ;   start vertical hair    lower.
  326.  
  327. ;    Draw the vertical hair:
  328.  
  329. colloop:
  330.     xor    es:[bx],dl    ;Draw (or erase) dot(s).
  331.     add    bx,2000h    ;Move up to next row.
  332.     jns    colloop1    ;If overflow,
  333.     add    bx,90-8000h    ;   correct address.
  334. colloop1:
  335.     loop    colloop
  336. ;
  337. ;    Now do the horizontal hair.
  338.  
  339.     mov    dx,graphx    ;Number    of dots    in a row.
  340.     call    rowmask        ;Get row length    in bytes plus mask.
  341.     not    dx        ;Invert    odd-word mask.
  342.     pop    bx        ;vram address of (0,y).
  343.  
  344. rowloop:
  345.     not    byte ptr es:[bx]    ;Invert    dots wholesale.
  346.     inc    bx
  347.     loop    rowloop
  348.  
  349.     xor    byte ptr es:[bx],dl    ;Get the odd word.
  350. ;
  351. adsmret:
  352.     pop    es
  353.     pop    bp
  354.     ret
  355. adsmark    endp
  356. ;
  357. ;
  358. ;
  359. ;    adsclr()
  360. ;
  361. ;    will erase the graphics    area.
  362.  
  363. ;    adswipe()
  364.  
  365. ;    will erase the whole screen.
  366.  
  367. ;
  368. adsclr    proc    far
  369.     push    bp
  370.     mov    dx,graphx    ;Graphics area width
  371.     mov    bp,graphy    ;   and    height.
  372.     xor    si,si        ;Start at top.
  373.     cmp    cline,0        ;If a status line,
  374.     je    clrwipe
  375.     add    si,below_cline    ;   start below    it.
  376.     jmp    short clrwipe
  377.  
  378. adswipe    label    far
  379.     push    bp
  380.     mov    dx,XSIZE    ;Total screen width
  381.     mov    bp,YSIZE    ;   and    height.
  382.     xor    si,si        ;Start at top.
  383.  
  384. ;    Numbers    of rows    to clear in bp,    number of columns in dx, starting
  385. ;    vram address in    si.
  386.  
  387. clrwipe:
  388.     push    es        ; Always save seg regs
  389.     mov    ax,graphseg    ;Base vram on es for stos.
  390.     mov    es,ax
  391.     call    rowmask        ;Convert dx to full bytes plus odd-byte    mask.
  392.     mov    bx,cx        ;Save byte count.
  393.     cld            ;Increment.
  394.     xor    ax,ax        ;Clear color source.
  395.  
  396. dsclr1:
  397.     mov    di,si        ;Starting address of row.
  398.     mov    cx,bx        ;Byte count.
  399.     rep    stosb        ;Clear the row.
  400.     and    es:[di],dl    ;Get the odd byte.
  401.     add    si,2000h    ;Bump row start    address.
  402.     jns    dsclr2
  403.     add    si,90-8000h
  404. dsclr2:    dec    bp        ;Count it.
  405.     jg    dsclr1        ;Done?
  406.  
  407.     pop    es
  408.     pop    bp
  409.     ret
  410. adsclr    endp
  411.  
  412. ;    Get number of complete bytes in    a row of graphics area in cx
  413. ;    and mask for the incomplete last byte in dx (0 bits for
  414. ;    included dots),    given number of    dots in    dx.  Clobber no    other
  415. ;    registers.
  416.  
  417. rowmask    proc    near
  418.     mov    cl,dl        ;Save low bits of count.
  419.     shr    dx,1        ;Get number of full bytes.
  420.     shr    dx,1
  421.     shr    dx,1
  422.     push    dx        ;Save momentarily.
  423.     and    cl,111b        ;Bits in odd byte.
  424.     mov    dx,-1        ;Set up    mask for
  425.     shr    dx,cl        ;   odd    byte.
  426.     xchg    dh,dl        ;That makes it backwards, of course.
  427.     pop    cx        ;Word count to cx.
  428.     ret
  429. rowmask    endp
  430.  
  431.  
  432.  
  433. ;    Routine    to draw    a character at specified coordinates:
  434.  
  435. ;    adschar(x, y, char)
  436.  
  437. ;    The character box is 9 wide by 14 high,    of which (x,y) is the
  438. ;    upper left corner.
  439. ;       The font definition  doesn't include the bottom row of the
  440. ;    character box nor the rightmost    column,    which are always zero.
  441.  
  442. adschar     proc    far
  443.     push    bp
  444.     mov    bp,sp
  445.     push    es        ; always save seg regs
  446.     mov    ax,graphseg    ;Point es to
  447.     mov    es,ax        ;   video ram.
  448.     cld
  449.  
  450.     mov    ch,13        ;Bytes in character definition.
  451.     mov    al,args+4    ;The character.
  452.     cmp    al,7Fh        ;We only print 20 thru 7F.
  453.     jg    adsc1
  454.     sub    al,20h        ;Bias to start of font table.
  455.     jge    adsc2
  456. adsc1:    xor    al,al        ;Print funny characters    as blanks.
  457. adsc2:    mul    ch        ;Find address of definition of char.
  458.     mov    si,offset dgroup:chartab
  459.     add    si,ax
  460.  
  461.     call    hcdot        ;Locate    corner in video    ram.
  462.     mov    dx,0111111100000000b    ;Mask of 9 zero    bits.
  463.     ror    dx,cl        ;Position it.
  464.     mov    di,bx        ;Ram offset to di.
  465.  
  466. dsch1:
  467.     lodsb            ;Get byte of character definition.
  468.     xor    ah,ah        ;Zero-extend it.
  469.     ror    ax,cl        ;Align it.
  470.     mov    bh,es:[di+1]    ;1st byte of vram it masks into.
  471.     mov    bl,es:[di]    ;And the second    byte.
  472.     and    bx,dx        ;Clear a row of    character box.
  473.     or    ax,bx        ;Set new bits.
  474.     mov    es:[di+1],ah    ;Put back the first byte.
  475.     mov    es:[di],al    ;And the second    byte.
  476.     add    di,2000h    ;Move to next row of character box.
  477.     jns    dsch2
  478.     add    di,90-8000h
  479. dsch2:    dec    ch        ;Loop.
  480.     jnz    dsch1
  481.  
  482.     and    es:[di+1],dh    ;Bottom    row of character box.
  483.     and    es:[di],dl    ;Both bytes.
  484.  
  485.     pop    es
  486.     pop    bp
  487.     ret
  488. adschar     endp
  489.  
  490.  
  491.  
  492.  
  493. ;    Routine    to set the character at    specified coordinates
  494. ;    reverse    video:
  495.  
  496. ;    dsrvid(x, y)
  497.  
  498. dsrvid    proc    far
  499.     push    bp
  500.     mov    bp,sp
  501.     push    es        ; always save seg regs
  502.     mov    ax,graphseg
  503.     mov    es,ax        ;Point es to video ram.
  504.  
  505.     call    hcdot        ;Get ram address of point.
  506.     mov    si,bx        ;Offset    into video ram.
  507.     mov    dx,1000000011111111b    ;Mask of 9 one bits.
  508.     ror    dx,cl        ;Position it.
  509.     mov    cx,14        ;Rows in character box.
  510.  
  511. dsrv1:
  512.     xor    es:[si],dl    ;Reverse one row of character.
  513.     xor    es:[si+1],dh    ;Both bytes of it.
  514.     add    si,2000h    ;Proceed to next row.
  515.     jns    dsrv2
  516.     add    si,90-8000h
  517. dsrv2:    loop    dsrv1
  518.  
  519.     pop    es
  520.     pop    bp
  521.     ret
  522. dsrvid    endp
  523.  
  524.  
  525. ;    Scroll up the bottom n lines of    the screen (the    text area):
  526.  
  527. ;    hcscroll(n)
  528.  
  529. hcscroll proc    far
  530.     push    bp
  531.     mov    bp,sp
  532.     push    ds
  533.     push    es        ; always save ALL seg regs
  534.     cld
  535.  
  536.     mov    al,args        ;Lines to scroll.
  537.     dec    al
  538.     mov    ah,14        ;At 14 rows of pixels
  539.     mul    ah        ;   per    line.
  540.     mov    bp,ax        ;Save for loop counter.
  541.     mov    ax,YSIZE    ;Get row number    of
  542.     sub    ax,bp        ;   first row to scroll    up.
  543.  
  544. ;    Compute    ram address of start of    that row.
  545.     mov    bx,ax        ;a copy.
  546.     shr    ax,1        ;Divide    by
  547.     shr    ax,1        ;   4 and multiply
  548.     mul    ninety        ;   by 90.
  549.     and    bx,11b        ;Low 2 bits of row number.
  550.     or    ah,hibits[bx]    ;Move to bits 14 and 13.
  551.     mov    si,ax        ;Put it    in si.
  552.     mov    di,si        ;Copy to destination register.
  553.  
  554. ;    The following gem computes the address of the start of the 14th
  555. ;    previous row, i.e., the    top row    of the previous    line of    text.
  556.     sub    di,(4000H+270)
  557.     jns    scr1
  558.     sub    di,90-8000h
  559. scr1:
  560.  
  561.     mov    ax,graphseg    ;Point both ds and
  562.     mov    ds,ax        ;   es to
  563.     mov    es,ax        ;   graphics ram.
  564. scr2:
  565.     mov    cx,90        ;Words in a row.
  566.     rep    movsb        ;Scroll    a row.
  567.     add    si,2000h-90    ;Move both pointers down a row.
  568.     jns    scr3
  569.     add    si,90-8000h
  570. scr3:    add    di,2000h-90
  571.     jns    scr4
  572.     add    di,90-8000h
  573. scr4:    dec    bp        ;Do requisite number of    rows.
  574.     jnz    scr2
  575.  
  576.     xor    ax,ax        ;Prepare to clear bottom line.
  577.     mov    dx,14        ;Number    of rows    in it.
  578. scr5:
  579.     mov    cx,90
  580.     rep    stosb        ;Move zeroes into a row.
  581.     add    di,2000h-90    ;Advance to next row.
  582.     jns    scr6
  583.     add    di,90-8000h
  584. scr6:    dec    dx
  585.     jnz    scr5
  586.  
  587.     pop    es
  588.     pop    ds
  589.     pop    bp
  590.     ret
  591. hcscroll endp
  592.  
  593.     endps    dsherca_
  594.     end
  595.